package com.ruibang.glass.produce.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.CommonErrorCode;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.produce.constant.Constants;
import com.ruibang.glass.produce.domain.req.GlassFluorescenceReq;
import com.ruibang.glass.produce.entity.GlassFluorescence;
import com.ruibang.glass.produce.mapper.GlassFluorescenceMapper;
import com.ruibang.glass.produce.service.GlassFluorescenceService;
import com.ruibang.glass.produce.util.ExcelStyleUtils;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 生产-理化-X荧光填写 服务实现类
 * </p>
 *
 * @author songJinKang
 * @since 2024-03-12
 */
@Slf4j
@Service
public class GlassFluorescenceServiceImpl extends ServiceImpl<GlassFluorescenceMapper, GlassFluorescence> implements GlassFluorescenceService {

    @Autowired
    private RedisSingleService redisService;

    @Override
    public IPage<GlassFluorescence> pageQuery(GlassFluorescenceReq glassFluorescenceReq) {
        QueryWrapper<GlassFluorescence> qw = new QueryWrapper<>();
        qw.lambda().eq(GlassFluorescence::getIsDelete, Constants.ZERO_STR);
        if (glassFluorescenceReq.getStartDate() != null && glassFluorescenceReq.getEndDate() != null) {
            qw.lambda().ge(GlassFluorescence::getDate, glassFluorescenceReq.getStartDate());
            qw.lambda().le(GlassFluorescence::getDate, glassFluorescenceReq.getEndDate());
        }
        qw.lambda().orderByDesc(GlassFluorescence::getCreateTime);
        return this.page(new Page<>(glassFluorescenceReq.getPageNo(), glassFluorescenceReq.getPageSize()), qw.lambda());
    }

    @Override
    public void delete(String id) {
        lambdaUpdate().eq(GlassFluorescence::getId, id).set(GlassFluorescence::getIsDelete, Constants.ONE_STR).update();
    }

    @Override
    public ResultBody reportForm(GlassFluorescenceReq glassFluorescenceReq) {
        List<GlassFluorescence> data = lambdaQuery().ge(GlassFluorescence::getDate, glassFluorescenceReq.getStartDate())
                .le(GlassFluorescence::getDate, glassFluorescenceReq.getEndDate()).eq(GlassFluorescence::getIsDelete, Constants.ZERO_STR).list();
        if (CollectionUtils.isNotEmpty(data)) {
            //根据时间分组与类型分组
            return ResultBody.success(data.stream().collect(Collectors.groupingBy(e -> e.getDate().toString(), Collectors.groupingBy(GlassFluorescence::getTime))));
        }
        return ResultBody.success();
    }

    @Override
    public void export(GlassFluorescenceReq glassFluorescenceReq, HttpServletResponse response) {
        glassFluorescenceReq.setPageNo(-1);
        glassFluorescenceReq.setPageSize(-1);
        IPage<GlassFluorescence> page = this.pageQuery(glassFluorescenceReq);
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<GlassFluorescence> glassFluorescenceList = page.getRecords();
            try {
                EasyExcel.write(response.getOutputStream(), GlassFluorescence.class)
                        .registerWriteHandler(ExcelStyleUtils.createTableStyle())
                        .sheet("history_data").doWrite(glassFluorescenceList);
            } catch (IOException e) {
                log.error("数据导出失败：{}", e.getMessage());
            }
        }
    }


    @Override
    public void exportReport(GlassFluorescenceReq glassFluorescenceReq, HttpServletResponse response) {
        glassFluorescenceReq.setPageNo(-1);
        glassFluorescenceReq.setPageSize(-1);
        IPage<GlassFluorescence> page = this.pageQuery(glassFluorescenceReq);
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<GlassFluorescence> glassFluorescenceList = page.getRecords();
            Map<String, Map<String, List<GlassFluorescence>>> map = glassFluorescenceList.stream().collect(Collectors.groupingBy(e -> e.getDate().toString(), Collectors.groupingBy(GlassFluorescence::getTime)));

            //set数据
            AtomicInteger sumRowCount = new AtomicInteger(0);

            //创建工作簿
            Workbook workbook = new SXSSFWorkbook(-1);
            Sheet abSheet = workbook.createSheet("产线玻璃成分（X荧光）");
            //合并单元格  设置主表头
            CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 2, 0, Constants.GLASS_FLUORESCENCE_TABLE_HEADERS.length - 1);
            abSheet.addMergedRegion(cellRangeAddress);
            Row mainHeadRow = abSheet.createRow(cellRangeAddress.getFirstRow());
            Cell mainCell = mainHeadRow.createCell(cellRangeAddress.getFirstColumn());
            mainCell.setCellStyle(mainHeadStyle(workbook));
            mainCell.setCellValue("产线玻璃成分（X荧光）");
            sumRowCount.addAndGet(Constants.THREE_INT);

            //设置表头
            Row headRow = abSheet.createRow(sumRowCount.get());
            for (int i = 0; i < Constants.GLASS_FLUORESCENCE_TABLE_HEADERS.length; i++) {
                Cell cell = headRow.createCell(i);
                cell.setCellValue(Constants.GLASS_FLUORESCENCE_TABLE_HEADERS[i]);
                cell.setCellStyle(headStyle(workbook));
            }
            sumRowCount.addAndGet(Constants.ONE_INT);


            //设置数据
            map.forEach((date, data) -> {
                int firstRow = sumRowCount.get();//日期开始行
                data.forEach((time, v) -> {
                    //填充单元格数据
                    int timeFirstRow = sumRowCount.get();//记录时间开始行
                    for (int i = 0; i < v.size(); i++) {
                        Row row = abSheet.createRow(sumRowCount.get());
                        GlassFluorescence glassFluorescence = v.get(i);
                        for (int j = 2; j < 15; j++) {
                            setData(glassFluorescence, row, workbook, j);
                        }
                        sumRowCount.addAndGet(Constants.ONE_INT);
                    }

                    //合并时间单元格
                    log.error("time:{} timeFirst :{} timeLast:{}", time, timeFirstRow, sumRowCount.get() - 1);
                    if (v.size() > 1) {
                        CellRangeAddress range = new CellRangeAddress(timeFirstRow, sumRowCount.get() - 1, 1, 1);
                        abSheet.addMergedRegion(range);
                        Row timeRow = abSheet.getRow(range.getFirstRow());
                        Cell timeCell = timeRow.createCell(1);
                        timeCell.setCellStyle(dataStyle(workbook));
                        timeCell.setCellValue(time);
                    } else {
                        Row timeRow = abSheet.getRow(sumRowCount.get() - 1);
                        Cell timeCell = timeRow.createCell(1);
                        timeCell.setCellStyle(dataStyle(workbook));
                        timeCell.setCellValue(time);
                    }

                });

                log.error("date:{} dateFirst:{} dateLast:{} ", date, firstRow, sumRowCount.get() - 1);
                if ((sumRowCount.get() - firstRow) > 1) {
                    //设置合并日期单元格
                    CellRangeAddress range = new CellRangeAddress(firstRow, sumRowCount.get() - 1, 0, 0);
                    abSheet.addMergedRegion(range);
                    Row dateRow = abSheet.getRow(range.getFirstRow());
                    Cell dateCell = dateRow.createCell(0);
                    dateCell.setCellStyle(dataStyle(workbook));
                    dateCell.setCellValue(date);
                } else {
                    Row dateRow = abSheet.getRow(sumRowCount.get() - 1);
                    Cell dateCell = dateRow.createCell(0);
                    dateCell.setCellStyle(dataStyle(workbook));
                    dateCell.setCellValue(date);
                }
            });


            //返回excel
            try {
                response.setContentType("application/vnd.ms-excel");
                response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("data.xlsx", "utf-8"));
                ServletOutputStream outputStream = response.getOutputStream();
                workbook.write(outputStream);
            } catch (IOException e) {
                throw new ServiceException(CommonErrorCode.MONITOR_DATA_EXPORT_FAIL.getCode(), CommonErrorCode.MONITOR_DATA_EXPORT_FAIL.getMsg());
            }

        }
    }

    @Override
    public void saveInfo(GlassFluorescence glassFluorescence) {
        glassFluorescence.setIsDelete(Constants.ZERO_STR);
        setUserName(glassFluorescence);
        this.save(glassFluorescence);
    }

    @Override
    public void edit(GlassFluorescence glassFluorescence) {
        setUserName(glassFluorescence);
        this.updateById(glassFluorescence);
    }

    private void setUserName(GlassFluorescence glassFluorescence) {
        String checkById = glassFluorescence.getCheckById();
        String createUserId = glassFluorescence.getCreateUserId();
        if (StringUtils.isNotBlank(checkById)) {
            Object userObj = redisService.hget(RedisKey.USER_GROUP_TYPE, checkById);
            if (userObj != null && StringUtils.isNotBlank(userObj.toString())) {
                glassFluorescence.setCheckBy(userObj.toString());
            }
        } else {
            glassFluorescence.setCheckBy("");
        }
        if (StringUtils.isNotBlank(createUserId)) {
            Object userObj = redisService.hget(RedisKey.USER_GROUP_TYPE, createUserId);
            if (userObj != null && StringUtils.isNotBlank(userObj.toString())) {
                glassFluorescence.setCreateUserName(userObj.toString());
            }
        } else {
            glassFluorescence.setCreateUserName("");
        }
    }

    private void setData(GlassFluorescence glassFluorescence, Row row, Workbook workbook, int cellPosition) {
        Cell cell = row.createCell(cellPosition);
        cell.setCellStyle(dataStyle(workbook));
        switch (cellPosition) {
            case 2: {
                cell.setCellValue(glassFluorescence.getArea());
                break;
            }
            case 3: {
                cell.setCellValue(glassFluorescence.getF1());
                break;
            }
            case 4: {
                cell.setCellValue(glassFluorescence.getF2());
                break;
            }
            case 5: {
                cell.setCellValue(glassFluorescence.getF3());
                break;
            }
            case 6: {
                cell.setCellValue(glassFluorescence.getF4());
                break;
            }
            case 7: {
                cell.setCellValue(glassFluorescence.getF5());
                break;
            }
            case 8: {
                cell.setCellValue(glassFluorescence.getF6());
                break;
            }
            case 9: {
                cell.setCellValue(glassFluorescence.getF7());
                break;
            }
            case 10: {
                cell.setCellValue(glassFluorescence.getF8());
                break;
            }
            case 11: {
                cell.setCellValue(glassFluorescence.getF9());
                break;
            }
            case 12: {
                cell.setCellValue(glassFluorescence.getF10());
                break;
            }
            case 13: {
                cell.setCellValue(glassFluorescence.getF11());
                break;
            }
            case 14: {
                cell.setCellValue(glassFluorescence.getRemark());
                break;
            }
            default: {
                cell.setCellValue("位置列：".concat(String.valueOf(cellPosition)));
            }
        }

    }


    /**
     * @Description: 主表头样式
     * @version v1.0
     * @author songJinKang
     * @date 2024-03-19 20:05
     */
    public static CellStyle headStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);
        style.setFont(font);
        font.setBold(true);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    /**
     * @Description: 表头样式
     * @version v1.0
     * @author songJinKang
     * @date 2024-03-19 20:05
     */
    public static CellStyle mainHeadStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 17);
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    /**
     * @Description: 数据样式
     * @version v1.0
     * @author songJinKang
     * @date 2024-03-19 20:05
     */
    private static CellStyle dataStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 9);
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }
}
